package edu.colorado.karl.intelsched;

/**
 * Weather is a data container class containing temperature and 
 * forecast information.
 */
public class Weather {
	private int lowT;			// Low Temperature (Fahrenheit)
	private int highT;			// High Temperature (Fahrenheit)
	private int wind;			// Wind speed (mph)
	private double precip;		// Precipitation chance
	private double snowch;		// Snow chance

	private static final int FORECAST_SIZE = 9;
	private boolean[] forecast;	/*	Forecast flag legend:
	 							 * 	[0]	Sunny
	 							 *  [1] Mostly Cloudy
	 							 *  [2] Partly Cloudy
	 							 *  [3] Windy
	 							 *  [4] Isolated Showers
	 							 *  [5] Isolated Snow Storms
	 							 *  [6] Rain
	 							 *  [7] Snow
	 							 *  [8] Fog
	 							 */
	
	/**
	 * Initializes a newly created <code>Weather</code> object.
	 */
	public Weather() {
		lowT = -666;
		highT = lowT;
		forecast = new boolean[FORECAST_SIZE];
		wind = 0;
		precip = 0;
		snowch = 0;
	}
	
	/**
	 * Constructs a new instance of a <code>Weather</code> object with the
	 * provided information.
	 * @param high	The predicted high temperature.
	 * @param low	The predicted low temperature.
	 * @param forecast	A set of flags indicating predicted forecast conditions.
	 * @param windSpeed	The predicted maximum wind speed.
	 * @param precipChance	The predicted chance of precipitation.
	 * @param snowChance	The predicted chance of snow precipitation.
	 */
	public Weather(int high, int low, boolean[] forecast, int windSpeed, 
					double precipChance, double snowChance) {
		lowT = low;
		highT = high;
		this.forecast = forecast;
		wind = windSpeed;
		precip = precipChance;
		snowch = snowChance;
	}

	/**
	 * Returns the stored predicted high temperature.
	 * @return the predicted high temperature
	 */
	public int getHighTemperature() {
		return highT;
	}

	/**
	 * Returns the stored predicted low temperature.
	 * @return the predicted low temperature
	 */
	public int getLowTemperature() {
		return lowT;
	}
	
	/**
	 * Returns the stored predicted maximum wind speed.
	 * @return the predicted maximum wind speed
	 */
	public int getWindSpeed() {
		return wind;
	}
	
	/**
	 * Returns the stored predicted chance of precipitation.  If the forecast 
	 * anticipated snow, this function returns 0.0 and 
	 * {@link #getSnowPrecipitationChance()} returns the actual estimated chance
	 * of precipitation.
	 * @return the predicted chance of precipitation
	 */
	public double getPrecipitationChance() {
		return precip;
	}
	
	/**
	 * Returns the stored predicted chance of snow precipitation.  If the 
	 * forecast did not predict snow, this function simply returns 0.0.
	 * @return the predicted chance of snow precipitation
	 */
	public double getSnowPrecipitationChance() {
		return snowch;
	}
	
	/**
	 * Returns true if the forecast predicted weather conditions of "sunny".  
	 * A forecast can also have additional weather conditions.
	 * @return whether or not the forecast predicted "sunny"
	 */
	public boolean isSunny() {
		return forecast[0];
	}
	
	/**
	 * Returns true if the forecast predicted weather conditions of "mostly cloudy".
	 * A forecast can also have additional weather conditions.
	 * @return whether or not the forecast predicted "mostly cloudy"
	 */
	public boolean isMostlyCloudy() {
		return forecast[1];
	}
	
	/**
	 * Returns true if the forecast predicted weather conditions of "partly cloudy".
	 * A forecast can also have additional weather conditions.
	 * @return whether or not the forecast predicted "partly cloudy"
	 */
	public boolean isPartlyCloudy() {
		return forecast[2];
	}
	
	/**
	 * Returns true if the forecast predicted weather conditions of "windy".
	 * A forecast can also have additional weather conditions.
	 * @return whether or not the forecast predicted "windy"
	 */
	public boolean isWindy() {
		return forecast[3];
	}
	
	/**
	 * Returns true if the forecast predicted weather conditions of 
	 * "isolated rain showers".  A forecast can also have additional weather
	 * conditions.  The chance of precipitation from the forecast can be
	 * retrieved from {@link #getPrecipitationChance()}.
	 * @return whether or not the forecast predicted "isolated rain showers"
	 */
	public boolean isIsolatedShowers() {
		return forecast[4];
	}
	
	/**
	 * Returns true if the forecast predicted weather conditions of "isolated
	 * snow showers".  A forecast can also have additional weather conditions.
	 * The chance of precipitation from the forecast can be retrieved from 
	 * {@link #getSnowPrecipitationChance()}.
	 * @return whether or not the forecast predicted "isolated snow showers"
	 */
	public boolean isIsolatedSnow() {
		return forecast[5];
	}
	
	/**
	 * Returns true if the forecast predicted rain.  A forecast can also have
	 * additional weather conditions.  The chance of precipitation from the 
	 * forecast can be retrieved from  {@link #getPrecipitationChance()}.
	 * @return whether or not the forecast predicted rain
	 */
	public boolean isRainy() {
		return forecast[6];
	}
	
	/**
	 * Returns true if the forecast predicted snow.  A forecast can also have
	 * additional weather conditions.
	 * The chance of precipitation from the forecast can be retrieved from 
	 * {@link #getSnowPrecipitationChance()}.
	 * @return whether or not the forecast predicted snow
	 */
	public boolean isSnowy() {
		return forecast[7];
	}

	/**
	 * Returns true if the forecast predicted fog.  A forecast can also have 
	 * additional weather conditions.
	 * @return whether or not the forecast predicted fog
	 */
	public boolean isFoggy() {
		return forecast[8];
	}
	
	/**
	 * Outputs the contents of the weather forecast to <code>System.out</code>.
	 */
	public void printData() {
		System.out.println("Weather Forecast:");
		System.out.println("High:\t" + highT + "F\t\tLow:\t" + lowT + "F");
		System.out.println("Sunny:\t\t\t" + forecast[0]);
		System.out.println("Mostly Cloudy:\t\t" + forecast[1]);
		System.out.println("Partly Cloudy:\t\t" + forecast[2]);
		System.out.println("Windy:\t\t\t" + forecast[3] + "\t(Wind speed: " + wind + " mph)");
		System.out.println("Isolated Showers:\t" + forecast[4]);
		System.out.println("Isolated Snow:\t\t" + forecast[5]);
		System.out.println("Rainy:\t\t\t" + forecast[6]);
		System.out.println("Snow:\t\t\t" + forecast[7]);
		System.out.println("Fog:\t\t\t" + forecast[8]);
		System.out.println("Chance of Precipitation:" + precip + "%");
		System.out.println("Chance of Snow:\t\t" + snowch + "%");
	}

	/**
	 * Outputs the contents of the weather forecast as an HTML String.
	 * @return an HTML-formatted string representing the contents of this
	 * Weather object.
	 */
	public String printDataHTML() {
		return "Weather Forecast:" + "<br />" +
			"High:\t" + highT + "F\t\tLow:\t" + lowT + "F" + "<br />" +
			"Sunny:\t\t\t" + forecast[0] + "<br />" +
			"Mostly Cloudy:\t\t" + forecast[1] + "<br />" +
			"Partly Cloudy:\t\t" + forecast[2] + "<br />" +
			"Windy:\t\t\t" + forecast[3] + "\t(Wind speed: " + wind + " mph)" + "<br />" +
			"Isolated Showers:\t" + forecast[4] + "<br />" +
			"Isolated Snow:\t\t" + forecast[5] + "<br />" +
			"Rainy:\t\t\t" + forecast[6] + "<br />" +
			"Snow:\t\t\t" + forecast[7] + "<br />" +
			"Fog:\t\t\t" + forecast[8] + "<br />" +
			"Chance of Precipitation:" + precip + "%" + "<br />" +
			"Chance of Snow:\t\t" + snowch + "%";
	}
	
	/**
	 * Sets the stored low temperature to <code>lowT</code>.
	 * @param lowT	The new predicted low temperature.
	 */
	public void setLowT(int lowT) {
		this.lowT = lowT;
	}

	/**
	 * Sets the stored high temperature to <code>highT</code>.
	 * @param highT	The new predicted high temperature.
	 */
	public void setHighT(int highT) {
		this.highT = highT;
	}

	/**
	 * Sets the stored maximum wind speed to <code>windSpeed</code>.
	 * @param windSpeed	The new predicted maximum wind speed.
	 */
	public void setWindSpeed(int windSpeed) {
		wind = windSpeed;
	}

	/**
	 * Sets the stored chance of precipitation to <code>precip</code>.  If the
	 * forecast predicted snow, this should be set to 0 and 
	 * {@link #setSnowChance(double)} should be used instead.
	 * @param precip	The new predicted chance of precipitation.
	 */
	public void setPrecip(double precip) {
		this.precip = precip;
	}

	/**
	 * Sets the stored chance of precipitation to <code>snowChance</code>.
	 * If the forecast did not
	 * predict snow, this should be set to 0 and {@link #setPrecip(double)}
	 * should be used instead.
	 * @param snowChance	The new predicted chance of snow.
	 */
	public void setSnowChance(double snowChance) {
		this.snowch = snowChance;
	}

	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of sunny.
	 * @param condition	The new prediction for sunny.
	 */
	public void setSunny(boolean condition) {
		forecast[0] = condition;
	}
	
	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of mostly cloudy.
	 * @param condition	The new prediction for mostly cloudy.
	 */
	public void setMostlyCloudy(boolean condition) {
		forecast[1] = condition;
	}
	
	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of partly cloudy.
	 * @param condition	The new prediction for partly cloudy.
	 */
	public void setPartlyCloudy(boolean condition) {
		forecast[2] = condition;
	}
	
	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of windy.
	 * @param condition	The new prediction for windy.
	 */
	public void setWindy(boolean condition) {
		forecast[3] = condition;
	}
	
	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of isolated rain showers.
	 * @param condition	The new prediction for isolated rain showers.
	 */
	public void setIsolatedShowers(boolean condition) {
		forecast[4] = condition;
	}
	
	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of isolated snow showers.
	 * @param condition	The new prediction for isolated snow showers.
	 */
	public void setIsolatedSnow(boolean condition) {
		forecast[5] = condition;
	}
	
	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of rain.
	 * @param condition	The new prediction for rain.
	 */
	public void setRainy(boolean condition) {
		forecast[6] = condition;
	}
	
	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of snow.
	 * @param condition	The new prediction for snow.
	 */
	public void setSnowy(boolean condition) {
		forecast[7] = condition;
	}

	/**
	 * If <code>condition</code> is true, this weather object now predicts a
	 * forecast of fog.
	 * @param condition	The new prediction for fog.
	 */
	public void setFoggy(boolean condition) {
		forecast[8] = condition;
	}
}
